package io.renren.modules.wms.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.common.utils.R;
import io.renren.modules.wms.dao.WeiboContentDao;
import io.renren.modules.wms.entity.DailyTempEntity;
import io.renren.modules.wms.entity.PictureInfoEntity;
import io.renren.modules.wms.entity.WeiboContentEntity;
import io.renren.modules.wms.entity.WeiboPicEntity;
import io.renren.modules.wms.service.DailyTempService;
import io.renren.modules.wms.service.PictureInfoService;
import io.renren.modules.wms.service.WeiboContentService;
import io.renren.modules.wms.service.WeiboPicService;
import io.renren.utils.ValidationUtil;
import io.renren.utils.WeiboContFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;


@Service("weiboContentService")
public class WeiboContentServiceImpl extends ServiceImpl<WeiboContentDao, WeiboContentEntity> implements WeiboContentService {

    /**
     * 微博总条数
     */
    private static final int WEIBO_TEMP_SIZE = 15;

    /**
     * 搞笑微博条数
     */
    private static final int WEIBO_FUN_SIZE = 13;

    /**
     * 情感微博条数
     */
    private static final int WEIBO_MOTION_SIZE = 2;

    /**
     * 模板路径
     */
    private static final String TEMP_PATH = "/usr/local/main/template.html";

    /**
     * 输出路径
     */
    private static final String OUTPUT_PATH = "/usr/local/main/output.html";

    @Resource
    private PictureInfoService pictureInfoService;

    @Resource
    private WeiboPicService weiboPicService;

    @Autowired
    private DailyTempService dailyTempService;

    @Override
    public R saveWeiboCont(WeiboContentEntity weiboContentEntity) {
        // 微博内容单词过滤
        String filterCont = WeiboContFilter.filter(weiboContentEntity.getWeiboContent());
        weiboContentEntity.setWeiboContent(filterCont);
        // 判断是否已经有重复内容
        WeiboContentEntity one = this.getOne(Wrappers.<WeiboContentEntity>lambdaQuery()
                .eq(WeiboContentEntity::getWeiboContent, weiboContentEntity.getWeiboContent()));

        if(one != null){
            return R.error("微博内容已经存在，微博id为：" + one.getId() + "；微博内容：" + one.getWeiboContent());
        }

        DateTime date = DateUtil.date();
        // 默认可用
        weiboContentEntity.setIsEnable(1);
        weiboContentEntity.setCreateTime(date);
        weiboContentEntity.setCreator("admin");
        weiboContentEntity.setModifiedTime(date);
        weiboContentEntity.setModifier("admin");

        // 保存内容
        this.save(weiboContentEntity);
        return R.ok(weiboContentEntity.getId());
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String weiboContent = String.valueOf(params.get("weiboContent"));
        String weiboType = String.valueOf(params.get("weiboType"));
        QueryWrapper<WeiboContentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StrUtil.isNotBlank(weiboType),WeiboContentEntity::getAuthorDesc, weiboType)
                .like(StrUtil.isNotBlank(weiboContent), WeiboContentEntity::getWeiboContent, weiboContent)
                .eq(WeiboContentEntity::getIsEnable, 1)
                .orderByDesc(WeiboContentEntity::getId);
        IPage<WeiboContentEntity> page = this.page(
                new Query<WeiboContentEntity>().getPage(params),
                queryWrapper
        );
        List<WeiboContentEntity> records = page.getRecords();
        setPics(records);
        return new PageUtils(page);
    }

    @Override
    public byte[] genFileByWeiboIds(List<Integer> integers) {
        QueryWrapper<WeiboContentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(WeiboContentEntity::getId, integers);
        List<WeiboContentEntity> list = this.list(queryWrapper);
        if(ValidationUtil.isEmptyList(list)){
            return null;
        }
        setPics(list);
        byte[] bytes = genByteContent(list);
        return bytes;
    }

    @Override
    public R genAutoTemp(List<Integer> idList) {
        List<WeiboContentEntity> tempList = new ArrayList<>();
        QueryWrapper<WeiboContentEntity> queryWrapper = new QueryWrapper<>();
        // 得到还没被用作模板的
        LambdaQueryWrapper<WeiboContentEntity> lambdaQueryWrapper = queryWrapper.lambda().eq(WeiboContentEntity::getIsEnable, 1).eq(WeiboContentEntity::getAuthorDesc, "搞笑");
        if(ValidationUtil.isNotEmptyList(idList)){
            lambdaQueryWrapper.notIn(WeiboContentEntity::getId, idList);
        }
//        queryWrapper = genFunTempQuery(lambdaQueryWrapper);
        List<WeiboContentEntity> list = this.list(lambdaQueryWrapper);
        if(ValidationUtil.isEmptyList(list)){
            return R.error("爬取微博数据暂时为空，请等待爬取");
        }
        // 取算法前面13个对象
        if(list.size() > WEIBO_FUN_SIZE){
            // 随机从list抽取13个元素
            addRandomEltoList(WEIBO_FUN_SIZE, list, tempList);
        }
        QueryWrapper<WeiboContentEntity> queryWrapper2 = new QueryWrapper<>();
        LambdaQueryWrapper<WeiboContentEntity> lambdaQueryWrapper2 = queryWrapper2.lambda().eq(WeiboContentEntity::getIsEnable, 1).eq(WeiboContentEntity::getAuthorDesc, "情感");
        if(ValidationUtil.isNotEmptyList(idList)){
            lambdaQueryWrapper2.notIn(WeiboContentEntity::getId, idList);
        }
//        queryWrapper2 = genMotionTempQuery(queryWrapper2);
        List<WeiboContentEntity> motionList = this.list(lambdaQueryWrapper2);
        // 取算法前面13个对象
        if(motionList.size() > WEIBO_MOTION_SIZE){
//            motionList = motionList.subList(0, WEIBO_MOTION_SIZE);
            // 随机从list抽取2个元素
            addRandomEltoList(WEIBO_MOTION_SIZE, motionList, tempList);
        }
        // 返回结果
        List<DailyTempEntity> resList = new ArrayList<>();
        for(WeiboContentEntity weiboContentEntity : tempList){
            DailyTempEntity dailyTempEntity = new DailyTempEntity();
            String weiboContent = weiboContentEntity.getWeiboContent();
            // 查询一下是否已经存在相关记录
            QueryWrapper<DailyTempEntity> dailyQueryWrapper = new QueryWrapper<>();
            dailyQueryWrapper.lambda().eq(DailyTempEntity::getWeiboContent, weiboContent);
            List<DailyTempEntity> dailyTempEntityList = dailyTempService.list(dailyQueryWrapper);
            // 不会保存相同内容
            if(ValidationUtil.isNotEmptyList(dailyTempEntityList)){
                continue;
            }
            QueryWrapper<WeiboPicEntity> weiboPicWrapper = new QueryWrapper<>();
            weiboPicWrapper.lambda().eq(WeiboPicEntity::getWeiboId, weiboContentEntity.getId());
            List<WeiboPicEntity> weiboPicList = weiboPicService.list(weiboPicWrapper);
            String reduce = "";
            if(ValidationUtil.isNotEmptyList(weiboPicList)){
                reduce = weiboPicList.stream().map(el -> String.valueOf(el.getPicId())).reduce((x, y) -> x + "," + y).get();
            }
            dailyTempEntity.setWeiboId(weiboContentEntity.getId());
            dailyTempEntity.setWeiboContent(weiboContent);
            dailyTempEntity.setPicIdList(reduce);
            // 保存
            dailyTempService.save(dailyTempEntity);
            resList.add(dailyTempEntity);
        }
        return R.ok(resList);
    }

    private void addRandomEltoList(int weiboMotionSize, List<WeiboContentEntity> motionList, List<WeiboContentEntity> tempList) {
        Random random = new Random();
        for(int i=0; i < weiboMotionSize; i ++){
            int n = random.nextInt(motionList.size());
            WeiboContentEntity weiboContentEntity = motionList.get(n);
            tempList.add(weiboContentEntity);
        }
    }

    /**
     * 逻辑删除
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R removeLogicByIds(List<Integer> ids) {
        Date date = DateUtil.date();
        List<WeiboContentEntity> collect = this.listByIds(ids).stream().collect(Collectors.toList());
        for (WeiboContentEntity weiboContentEntity : collect){
            // 闭包赋值置为不可用
            weiboContentEntity.setIsEnable(0);
            // 不可用的日期
            weiboContentEntity.setModifiedTime(date);
        }
        // 批量保存
        this.updateBatchById(collect);
        // 删除所有temp表数据
        dailyTempService.removeAll();
        return R.ok();
    }

    /**
     * 生成情感模板的算法 2 条（重要）
     * @param queryWrapper
     * @return
     */
    private QueryWrapper<WeiboContentEntity> genMotionTempQuery(QueryWrapper<WeiboContentEntity> queryWrapper) {
        // 随机算法
        return queryWrapper;
    }

    /**
     * 生成搞笑模板的算法 13 条（重要）
     * @param queryWrapper
     * @return
     */
    private QueryWrapper genFunTempQuery(QueryWrapper<WeiboContentEntity> queryWrapper) {
        return queryWrapper;
    }

    /**
     * 得到输出流
     * @param list
     * @return
     */
    private  byte[] genByteContent(List<WeiboContentEntity> list) {
        if(ValidationUtil.isEmptyList(list)){
            return null;
        }
        int listIndex = 1;

        List<String> resList = new ArrayList<>();

        // 读取temp模板
        List<String> lines = FileUtil.readLines(TEMP_PATH, "utf-8");
        // 将list内容写入模板中
        for(String line : lines){
            if(!line.contains("placeholder")){
                resList.add(line);
                continue;
            }
            if(!line.contains(String.valueOf(listIndex)) || listIndex > list.size()){
                continue;
            }
            WeiboContentEntity weiboContentEntity = list.get(listIndex - 1);
            String weiboContent = weiboContentEntity.getWeiboContent();
            List<String> picPathList = weiboContentEntity.getPicPathList();
            String picDiv = genPicHtmlStr(picPathList);
            String placeholder = line.replace("标题" + String.valueOf(listIndex),
                    weiboContent).replace("placeholder", picDiv);
            resList.add(placeholder);
            listIndex ++;
        }

        // 保存至output.html file中
        FileWriter writer = new FileWriter(OUTPUT_PATH);
        File file = writer.appendLines(resList);
        // 得到file bytes
        byte[] bytes = FileUtil.readBytes(file);
        return bytes;
    }

    /**
     * 生成模板图片内容
     * @param picPathList
     * @return
     */
    private String genPicHtmlStr(List<String> picPathList) {
        if(ValidationUtil.isEmptyList(picPathList)){
            return "";
        }
        String finalPicDiv = "";
        String temp = "<div class='pic-margin'><img src='{picUrl}'/></div>";
        for(String path : picPathList){
            String replace = temp.replace("{picUrl}", path);
            finalPicDiv += replace;
        }
        return finalPicDiv;
    }

    /**
     * 构造一整条微博的实体
     * @param records
     */
    private void setPics(List<WeiboContentEntity> records){
        for(WeiboContentEntity weiboContentEntity: records){
            Integer id = weiboContentEntity.getId();
            List<PictureInfoEntity> listPic = pictureInfoService.queryByWeiboId(id);
            if(ValidationUtil.isEmptyList(listPic)){
                continue;
            }
            List<String> collect = listPic.stream().map(el -> "http://" + el.getHttpUrl()).collect(Collectors.toList());
            weiboContentEntity.setPicPathList(collect);
        }
    }


}